import 'dart:convert';
import 'dart:io';
import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:path_provider/path_provider.dart';
import 'package:image_picker/image_picker.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:audioplayers/audioplayers.dart';
import 'package:intl/intl.dart';
import 'timeline_painter.dart';

/*
 * 模块关系图 - 请同步维护
 * 重要：涉及模块的修改全部需要同步修改本图
 * 
 * SpaxisApp (应用入口)
 * ├── SpaxisManager (状态管理)
 * │   ├── SpaxisEvent (数据模型)
 * │   ├── Destiny (命迹数据模型)
 * │   ├── TimeUnitConfig (时间配置)
 * │   └── 数据持久化
 * ├── SpaxisHomePage (主界面)
 * │   ├── TimelineCanvas (时间轴画布)
 * │   │   ├── TimelinePainter (绘制器) → lib/timeline_painter.dart
 * │   │   └── 手势处理
 * │   ├── 对话框组件
 * │   │   ├── EventEditDialog
 * │   │   ├── EventDetailsDialog
 * │   │   ├── ReviewSettingsPage (回顾设置)
 * │   │   └── ReviewPlayerPage (回顾播放)
 * │   ├── _ZoomButton (缩放按钮)
 * │   └── 设置页面
 * └── 工具类
 *     ├── TextParser (文本解析)
 *     ├── TimelineUtils (工具函数) → lib/timeline_painter.dart
 *     ├── TimelineCanvasStateHelper → lib/timeline_painter.dart
 *     └── HitEvent (事件命中检测) → lib/timeline_painter.dart
 * 
 * 模块间依赖关系：
 * - SpaxisManager 作为核心状态管理器，被所有UI组件依赖
 * - TimelineCanvas 依赖 SpaxisManager 获取数据和状态
 * - TimelinePainter 依赖 SpaxisManager 进行绘制
 * - 对话框组件通过 SpaxisManager 进行数据操作
 * - ReviewSettingsPage 和 ReviewPlayerPage 处理回顾功能
 * 
 * 数据流向：
 * 1. 用户交互 → TimelineCanvas 手势处理
 * 2. 手势事件 → SpaxisManager 状态更新
 * 3. 状态变化 → TimelinePainter 重新绘制
 * 4. UI更新 → 用户看到变化
 * 
 * 架构模式：MVC + Provider状态管理
 */


void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // 请求相册权限
  await Permission.photos.request();
  runApp(SpaxisApp());
}

class ReviewSettingsPage extends StatefulWidget {
  final SpaxisManager manager;

  const ReviewSettingsPage({super.key, required this.manager});

  @override
  ReviewSettingsPageState createState() => ReviewSettingsPageState();
}

class ReviewSettingsPageState extends State<ReviewSettingsPage> {
  late List<SpaxisEvent> _events;
  final List<String> _musicOptions = ['无音乐', '背景音乐1', '背景音乐2', '背景音乐3', '背景音乐4', '背景音乐5'];
  // 存储每个事件的音乐选择，键为事件ID，值为音乐名称
  final Map<String, String> _eventMusicSelections = {};
  // 存储每个事件的音乐启用状态
  final Map<String, bool> _eventMusicEnabled = {};

  @override
  void initState() {
    super.initState();
    _events = List.from(widget.manager.events);
    // 初始化每个事件的音乐设置
    for (final event in _events) {
      _eventMusicSelections[event.id] = '无音乐';
      _eventMusicEnabled[event.id] = true;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('回顾设置')),
      body: Padding(
        padding: EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children:[
            const Text('事件顺序设置', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
            Expanded(
              child: _events.isEmpty 
                ? Center(
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Icon(Icons.event_busy, size: 64, color: Colors.grey),
                        SizedBox(height: 16),
                        Text('暂无事件', style: TextStyle(fontSize: 18, color: Colors.grey)),
                        SizedBox(height: 8),
                        Text('请先添加一些事件', style: TextStyle(fontSize: 14, color: Colors.grey[600])),
                      ],
                    ),
                  )
                : ReorderableListView(
                children: _events.map((event) => ListTile(
                  key: Key(event.id),
                  title: Text(event.title),
                  subtitle: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      Text('${event.startTime.year}-${event.startTime.month}-${event.startTime.day}'),
                      // 添加音乐选择控件
                      Row(
                        children: [
                          Checkbox(
                            value: _eventMusicEnabled[event.id] ?? true,
                            onChanged: (value) => setState(() {
                              _eventMusicEnabled[event.id] = value!;
                            }),
                            materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
                          ),
                          const Text('音乐:', style: TextStyle(fontSize: 14)),
                          const SizedBox(width: 8),
                          Expanded(
                            child: DropdownButton<String>(
                              value: _eventMusicSelections[event.id],
                              items: _musicOptions.map((music) => DropdownMenuItem(
                                value: music,
                                child: Text(music, style: TextStyle(fontSize: 14)),
                              )).toList(),
                              onChanged: _eventMusicEnabled[event.id] ?? true
                                  ? (value) => setState(() {
                                      _eventMusicSelections[event.id] = value!;
                                    })
                                  : null,
                              isExpanded: true,
                              underline: const SizedBox(),
                              style: TextStyle(fontSize: 14, color: Colors.black87),
                            ),
                          ),
                        ],
                      ),
                    ],
                  ),
                )).toList(),
                onReorder: (oldIndex, newIndex) {
                  setState(() {
                    if (oldIndex < newIndex) newIndex--;
                    final item = _events.removeAt(oldIndex);
                    _events.insert(newIndex, item);
                  });
                },
              ),
            ),

          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.play_arrow),
        onPressed: () {
          // 这里将实现播放回顾功能
          Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => ReviewPlayerPage(
              events: _events,
              eventMusicSelections: _eventMusicSelections,
              eventMusicEnabled: _eventMusicEnabled,
            )),
          );
        },
      ),
    );
  }
}

class ReviewPlayerPage extends StatefulWidget {
  final List<SpaxisEvent> events;
  final Map<String, String> eventMusicSelections;
  final Map<String, bool> eventMusicEnabled;

  const ReviewPlayerPage({
    super.key,
    required this.events,
    required this.eventMusicSelections,
    required this.eventMusicEnabled,
  });

  @override
  _ReviewPlayerPageState createState() => _ReviewPlayerPageState();
}

class _ReviewPlayerPageState extends State<ReviewPlayerPage> {
  late AudioPlayer _audioPlayer;
  bool _autoPlay = false; // 自动播放开关状态
  bool _isPlaying = false;
  Duration _currentPosition = Duration.zero;
  Duration _totalDuration = Duration.zero;
  int _currentEventIndex = 0;
  bool _musicEnabled = true; // 背景音乐开关状态
  List<SpaxisEvent> _events = []; // 事件列表
  SpaxisEvent? _currentEvent;
  ImageProvider? _backgroundImage;

  @override
  void initState() {
    super.initState();
    _audioPlayer = AudioPlayer();
    _initAudioPlayer();
    _loadEvents();
  }

  Future<void> _initAudioPlayer() async {
    await _audioPlayer.setReleaseMode(ReleaseMode.stop);

    _audioPlayer.onDurationChanged.listen((duration) {
      setState(() => _totalDuration = duration);
    });

    _audioPlayer.onPositionChanged.listen((position) {
      setState(() => _currentPosition = position);
    });

    _audioPlayer.onPlayerComplete.listen((_) {
      setState(() => _isPlaying = false);
      if (_autoPlay) {
    _nextEvent(); // 自动播放下一个事件
  }
    });
  }

  Future<void> _loadEvents() async {
    // 加载事件数据
    setState(() {
      _events = widget.events; // 从构造函数获取事件列表
      if (_events.isNotEmpty) {
        _currentEventIndex = 0;
        _currentEvent = _events[_currentEventIndex];
        _loadBackgroundImage();
        if (_musicEnabled && _currentEvent?.backgroundMusicPath != null) {
          _playBackgroundMusic();
        }
      }
    });
  }

  Future<void> _loadBackgroundImage() async {
    if (_currentEvent?.backgroundImagePath != null) {
      setState(() {
        _backgroundImage = FileImage(File(_currentEvent!.backgroundImagePath!));
      });
    }
  }

  Future<void> _playBackgroundMusic() async {
    if (_currentEvent?.backgroundMusicPath != null) {
      await _audioPlayer.play(DeviceFileSource(_currentEvent!.backgroundMusicPath!));
      setState(() => _isPlaying = true);
    }
  }

  void _nextEvent() {
    if (_currentEventIndex < _events.length - 1) {
      setState(() {
        _currentEventIndex++;
        _currentEvent = _events[_currentEventIndex];
        _loadBackgroundImage();
        _audioPlayer.stop();
        if (_musicEnabled && _currentEvent?.backgroundMusicPath != null) {
          _playBackgroundMusic();
        }
      });
    } else if (_autoPlay) {
      // 自动播放循环到第一个事件
      setState(() {
        _currentEventIndex = 0;
        _currentEvent = _events[_currentEventIndex];
        _loadBackgroundImage();
        _audioPlayer.stop();
        if (_musicEnabled && _currentEvent?.backgroundMusicPath != null) {
          _playBackgroundMusic();
        }
      });
    }
  }

  void _prevEvent() {
    if (_currentEventIndex > 0) {
      setState(() {
        _currentEventIndex--;
        _currentEvent = _events[_currentEventIndex];
        _loadBackgroundImage();
        _audioPlayer.stop();
        if (_musicEnabled && _currentEvent?.backgroundMusicPath != null) {
          _playBackgroundMusic();
        }
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _currentEvent == null ? Center(child: CircularProgressIndicator()) : Stack(
        children: [
            // 背景图片
            _buildBackgroundImage(),
            // 事件内容
            _buildEventContent(),
            // 左右切换手势区域
            _buildNavigationGestures(),
            _buildTopControls(), // 确保这些方法在类内部可见
            _buildBottomControls(),
          ],
      ),
    );
  }

  Widget _buildBackgroundImage() {
    return _backgroundImage != null ? Container(
      decoration: BoxDecoration(
        image: DecorationImage(
          image: _backgroundImage!,
          fit: BoxFit.cover,
          colorFilter: ColorFilter.mode(Colors.black54, BlendMode.darken), // 暗化背景确保文字可读性
        ),
      ),
    ) : Container(color: Colors.black);
  }

  Widget _buildEventContent() {
    return Column(
      children: [
        // 标题放在最上方
        Padding(
          padding: EdgeInsets.only(top: 80, left: 24, right: 24),
          child: Text(
            _currentEvent!.title,
            style: TextStyle(
              fontSize: 28,
              fontWeight: FontWeight.bold,
              color: Colors.white,
              shadows: [Shadow(color: Colors.black, blurRadius: 4)],
            ),
            textAlign: TextAlign.center,
          ),
        ),
        // 描述放在界面下方四分之一处
        Expanded(
          child: Align(
            alignment: Alignment.bottomCenter,
            child: Padding(
              padding: EdgeInsets.only(bottom: MediaQuery.of(context).size.height / 4, left: 24, right: 24),
              child: Text(
                _currentEvent!.description,
                style: TextStyle(
                  fontSize: 18,
                  color: Colors.white,
                  shadows: [Shadow(color: Colors.black, blurRadius: 4)],
                ),
                textAlign: TextAlign.center,
              ),
            ),
          ),
        ),
      ],
    );
  }

  Widget _buildNavigationGestures() {
    return Row(
      children: [
        // 左侧点击区域
        Expanded(
          child: GestureDetector(
            onTap: _prevEvent,
            child: Container(color: Colors.transparent),
          ),
        ),
        // 右侧点击区域
        Expanded(
          child: GestureDetector(
            onTap: _nextEvent,
            child: Container(color: Colors.transparent),
          ),
        ),
      ],
    );
  }

  Widget _buildTopControls() {
  return Align(
    alignment: Alignment.topRight,
    child: Padding(
      padding: EdgeInsets.only(top: 40, right: 20),
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          // 音乐开关按钮
          Row(
            children: [
              Icon(Icons.music_note, color: Colors.white, size: 24),
              Switch(
                value: _musicEnabled,
                onChanged: (value) {
                  setState(() => _musicEnabled = value);
                  if (value && _currentEvent?.backgroundMusicPath != null) {
                    _playBackgroundMusic();
                  } else {
                    _audioPlayer.pause();
                  }
                },
                activeColor: Colors.blue,
                materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
              ),
            ],
          ),
          SizedBox(width: 16),
          // 退出按钮
          IconButton(
            icon: Icon(Icons.close, color: Colors.white, size: 28),
            onPressed: () => Navigator.pop(context),
          ),
        ],
      ),
    ),
  );
}

  Widget _buildBottomControls() {
    return Align(
      alignment: Alignment.bottomRight,
      child: Padding(
        padding: EdgeInsets.only(bottom: 40, right: 40),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.end,
          children: [
            if (_totalDuration.inSeconds > 0)
              Text(
                '${_currentPosition.inSeconds}/${_totalDuration.inSeconds}s',
                style: TextStyle(color: Colors.white, fontSize: 12),
              ),
            SizedBox(height: 8),
            Row(
              children: [
                Icon(_isPlaying ? Icons.pause : Icons.play_arrow, color: Colors.white),
                Switch(
                  value: _autoPlay,
                  onChanged: (value) => setState(() => _autoPlay = value),
                  activeColor: Colors.blue,
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    _audioPlayer.dispose();
    super.dispose();
  }
}


class SpaxisApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => SpaxisManager(),
      child: MaterialApp(
        title: '命迹',
        theme: ThemeData(
          primarySwatch: Colors.blue,
          visualDensity: VisualDensity.adaptivePlatformDensity,
        ),
        home: SpaxisHomePage(),
      ),
    );
  }


}

// 数据模型
class SpaxisEvent {
  final String id;
  String title;
  DateTime startTime;
  DateTime? endTime;
  String description;
  List<String> tags;
  int priority;
  Color color;
  double minZoomLevel;
  String? backgroundImagePath; // 新增背景图片路径属性
  String? backgroundMusicPath; // 背景音乐路径属性

  SpaxisEvent({
    required this.id,
    required this.title,
    required this.startTime,
    this.endTime,
    this.description = '',
    this.tags = const [],
    this.priority = 1,
    this.color = Colors.blue,
    this.minZoomLevel = 1.0,
    this.backgroundImagePath, // 添加到构造函数
    this.backgroundMusicPath, // 背景音乐路径参数
  });

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'title': title,
      'start_time': startTime.toIso8601String(),
      'end_time': endTime?.toIso8601String(),
      'description': description,
      'tags': tags,
      'priority': priority,
      'color': color.value,
      'min_zoom_level': minZoomLevel,
    'background_image_path': backgroundImagePath, // 添加到JSON序列化
    'background_music_path': backgroundMusicPath, // 添加背景音乐路径到JSON
  };
  }

  factory SpaxisEvent.fromJson(Map<String, dynamic> json) {
    return SpaxisEvent(
      id: json['id'] as String,
      title: json['title']!,
      startTime: DateTime.parse(json['start_time']),
      endTime:
          json['end_time'] != null ? DateTime.parse(json['end_time']) : null,
      description: json['description'] ?? '',
      tags: List<String>.from(json['tags'] ?? []),
      priority: json['priority'] ?? 1,
      color: Color(json['color'] ?? Colors.blue.value),
      minZoomLevel: (json['min_zoom_level'] ?? 1.0).toDouble(),
      backgroundImagePath: json['background_image_path'], // 从JSON反序列化
      backgroundMusicPath: json['background_music_path'], // 从JSON反序列化背景音乐路径
    );
  }
}

// 命迹数据模型
class Destiny {
  final String id;
  String name;
  List<SpaxisEvent> events;

  Destiny({
    required this.id,
    required this.name,
    List<SpaxisEvent>? events,
  }) : events = events ?? [];

  // 转换为JSON
  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'name': name,
      'events': events.map((event) => event.toJson()).toList(),
    };
  }

  // 从JSON创建Destiny
  factory Destiny.fromJson(Map<String, dynamic> json) {
    return Destiny(
      id: json['id'] as String,
      name: json['name'] as String,
      events: (json['events'] as List)
          .map((eventJson) => SpaxisEvent.fromJson(eventJson))
          .toList(),
    );
  }
}

// 文本解析工具类
class TextParser {
  // 支持的日期格式
  static final List<DateFormat> dateFormats = [
    DateFormat('yyyy-MM-dd'),
    DateFormat('yyyy/MM/dd'),
    DateFormat('MM-dd-yyyy'),
    DateFormat('dd/MM/yyyy'),
    DateFormat('yyyy年MM月dd日'),
    DateFormat('MM月dd日'),
    DateFormat('yyyy-MM'),
    DateFormat('yyyy年MM月'),
  ];

  // 解析文本提取事件
  static List<SpaxisEvent> parseText(String text) {
    final events = <SpaxisEvent>[];
    final lines = text.split(RegExp(r'[\n。；;！!?？]')).where((l) => l.trim().isNotEmpty);
    
    for (final line in lines) {
      final trimmedLine = line.trim();
      if (trimmedLine.isEmpty) continue;
      
      // 提取日期
      DateTime? startTime;
      DateTime? endTime;
      String content = trimmedLine;
      
      // 尝试匹配各种日期格式
      for (final format in dateFormats) {
        try {
          // 查找日期字符串
          final pattern = format.pattern;
          if (pattern != null) {
            // 转义特殊字符，创建正确的正则表达式
            final escapedPattern = pattern
                .replaceAll('yyyy', r'\d{4}')
                .replaceAll('MM', r'\d{2}')
                .replaceAll('dd', r'\d{2}')
                .replaceAll('年', '年')
                .replaceAll('月', '月')
                .replaceAll('日', '日')
                .replaceAll('-', r'\-')
                .replaceAll('/', r'\/');
            
            final match = RegExp(escapedPattern).firstMatch(trimmedLine);
            if (match != null) {
              final matchedText = match.group(0);
              if (matchedText != null && matchedText.isNotEmpty) {
                startTime = format.parse(matchedText);
                endTime = startTime.add(Duration(days: 1));
                content = trimmedLine.replaceAll(matchedText, '').trim();
                break;
              }
            }
          }
        } catch (e) {
          continue;
        }
      }
      
      // 如果没有找到明确日期，使用当前日期
      startTime ??= DateTime.now();
      endTime ??= startTime.add(Duration(days: 1));
      
      // 生成标题（取前15个字或根据关键词）
      final title = content.length > 15 ? content.substring(0, 15) + '...' : content;
      
      // 创建事件对象
      final event = SpaxisEvent(
        id: UniqueKey().toString(),
        title: title,
        startTime: startTime,
        endTime: endTime,
        description: content,
        color: _getRandomColor(),
      );
      events.add(event);
    }
    
    return events;
  }
  
  // 生成随机颜色用于事件区分
  static Color _getRandomColor() {
    final colors = [
      Colors.blue, Colors.green, Colors.orange, Colors.purple,
      Colors.red, Colors.teal, Colors.indigo, Colors.amber
    ];
    return colors[math.Random().nextInt(colors.length)];
  }
}

class SpaxisManager extends ChangeNotifier {
  List<Destiny> _destinies = [];
  int _selectedDestinyIndex = 0;
  DateTime _viewportStart = DateTime.now().subtract(Duration(days: 365));
  DateTime _viewportEnd = DateTime.now().add(Duration(days: 365));
  double _zoomLevel = 1.0;
  SpaxisEvent? _selectedEvent;

  int _trackCount = 1;
  int get trackCount => _trackCount;
  set trackCount(int value) {
    if (_trackCount != value) {
      _trackCount = value.clamp(1, 5);
      notifyListeners();
    }
  }

  // 新增命迹管理方法
  List<Destiny> get destinies => _destinies;
  int get selectedDestinyIndex => _selectedDestinyIndex;

  void selectDestiny(int index) {
    if (index >= 0 && index < _destinies.length) {
      _selectedDestinyIndex = index;
      notifyListeners();
    }
  }

  void addDestiny(String name) {
    final newDestiny = Destiny(
      id: UniqueKey().toString(),
      name: name,
      events: [],
    );
    _destinies.add(newDestiny);
    _selectedDestinyIndex = _destinies.length - 1;
    notifyListeners();
  }

  void deleteDestiny(int index) {
    if (index >= 0 && index < _destinies.length) {
      _destinies.removeAt(index);
      if (_selectedDestinyIndex >= index) {
        _selectedDestinyIndex = _selectedDestinyIndex > 0 ? _selectedDestinyIndex - 1 : 0;
      }
      if (_destinies.isEmpty) {
        _createDefaultDestiny();
      }
      notifyListeners();
      _saveToFile();
    }
  }

  // 初始化默认命迹
  void _createDefaultDestiny() {
    _destinies.add(Destiny(
      id: UniqueKey().toString(),
      name: "默认命迹",
    ));
    _selectedDestinyIndex = 0;
  }

  // 访问当前选中命迹的名称
  String get timelineName => _destinies.isNotEmpty ? _destinies[_selectedDestinyIndex].name : "我的事件线";
  set timelineName(String name) {
    if (_destinies.isNotEmpty && _destinies[_selectedDestinyIndex].name != name) {
      _destinies[_selectedDestinyIndex].name = name;
      notifyListeners();
      _saveToFile();
    }
  }

  // 获取当前选中命迹的事件列表
  List<SpaxisEvent> get events => _destinies.isNotEmpty ? _destinies[_selectedDestinyIndex].events : [];
  DateTime get viewportStart => _viewportStart;
  DateTime get viewportEnd => _viewportEnd;
  double get zoomLevel => _zoomLevel;
  SpaxisEvent? get selectedEvent => _selectedEvent;

  // 获取当前视口的总时间跨度（毫秒）
  int get viewportDurationMs =>
      _viewportEnd.difference(_viewportStart).inMilliseconds;

  void addEvent(SpaxisEvent event) {
    if (_destinies.isEmpty) {
      _createDefaultDestiny();
    }
    _destinies[_selectedDestinyIndex].events.add(event);
    _saveToFile();
    notifyListeners();
  }

  void updateEvent(SpaxisEvent event) {
    if (_destinies.isEmpty) return;
    final index = _destinies[_selectedDestinyIndex].events.indexWhere((e) => e.id == event.id);
    if (index != -1) {
      _destinies[_selectedDestinyIndex].events[index] = event;
      _saveToFile();
      notifyListeners();
    }
  }

  void removeEvent(String eventId) {
    if (_destinies.isEmpty) return;
    _destinies[_selectedDestinyIndex].events.removeWhere((e) => e.id == eventId);
    _saveToFile();
    notifyListeners();
  }

  // 清空所有事件
  void clearAllEvents() {
    if (_destinies.isEmpty) return;
    _destinies[_selectedDestinyIndex].events.clear();
    _saveToFile();
    notifyListeners();
  }

  // 重置为示例数据
  void resetToSampleData() {
    if (_destinies.isEmpty) {
      _createDefaultDestiny();
    }
    _destinies[_selectedDestinyIndex].events = _createSampleEvents();
    _saveToFile();
    notifyListeners();
  }

  // 添加示例事件创建方法
  List<SpaxisEvent> _createSampleEvents() {
    final now = DateTime.now();
    return [
      SpaxisEvent(
        id: '1',
        title: '初始事件',
        description: '这是一个示例事件',
        startTime: now.subtract(Duration(days: 7)),
        endTime: now,
        color: Colors.blue,
      ),
      SpaxisEvent(
        id: '2',
        title: '未来事件',
        description: '这是一个未来的示例事件',
        startTime: now.add(Duration(days: 7)),
        endTime: now.add(Duration(days: 14)),
        color: Colors.green,
      ),
    ];
  }

  void setViewport(DateTime start, DateTime end) {
    _viewportStart = start;
    _viewportEnd = end;
    _saveToFile(); // 立即保存
    notifyListeners();
  }

  void setZoomLevel(double zoom) {
    // 严格限制缩放范围，防止数值溢出
    const minZoom = 0.01; // 最小缩放（约27年视图）
    const maxZoom = 525600.0; // 最大缩放（约1分钟视图）

    // 应用强阻力效果
    if (zoom < minZoom) {
      // 当超出最小缩放时，应用指数衰减阻力
      final overflow = minZoom - zoom;
      final resistance = math.exp(-overflow * 10) * 0.001;
      _zoomLevel = minZoom - resistance;
    } else if (zoom > maxZoom) {
      // 当超出最大缩放时，应用指数衰减阻力
      final overflow = zoom - maxZoom;
      final resistance = math.exp(-overflow / maxZoom * 10) * 1000;
      _zoomLevel = maxZoom + resistance;
    } else {
      _zoomLevel = zoom;
    }

    // 确保数值不会变成无穷大或NaN
    if (!_zoomLevel.isFinite || _zoomLevel <= 0) {
      _zoomLevel = 1.0;
    }

    notifyListeners();
    _saveToFile(); // 立即保存
  }

  void panViewport(double deltaX, double canvasWidth) {
    if (canvasWidth <= 0) return;

    final totalDuration = viewportDurationMs;
    if (totalDuration <= 0) return;

    final deltaTime = (deltaX / canvasWidth) * totalDuration;
    final deltaTimeMs = deltaTime.round();

    try {
      final newStart = _viewportStart.add(Duration(milliseconds: deltaTimeMs));
      final newEnd = _viewportEnd.add(Duration(milliseconds: deltaTimeMs));

      // 验证新的时间范围是否合理
      if (newStart.isAfter(DateTime(1900)) && newEnd.isBefore(DateTime(2200))) {
        _viewportStart = newStart;
        _viewportEnd = newEnd;
        notifyListeners();
        _saveToFile(); // 立即保存
      }
    } catch (e) {
      // 如果时间计算出错，重置到合理范围
      _resetToSafeRange();
    }
  }

  void zoomViewport(double scaleFactor, double centerX, double canvasWidth) {
    if (canvasWidth <= 0 || scaleFactor <= 0 || !scaleFactor.isFinite) return;

    // 限制缩放因子范围，防止极端操作
    scaleFactor = math.max(0.1, math.min(10.0, scaleFactor));

    final centerRatio = 0.5; // 视口中心比例，表示视口中心在画布上的相对位置
    final currentDuration = viewportDurationMs;

    if (currentDuration <= 0) return;

    try {
      final newDuration = (currentDuration / scaleFactor).round();

      // 防止视口时间跨度过小或过大
      if (newDuration < 60000) return; // 最小1分钟
      if (newDuration > 3153600000000) return; // 最大100年

      final centerTime = _viewportStart
          .add(Duration(milliseconds: (currentDuration * centerRatio).round()));
      final halfNewDuration = (newDuration / 2).round();

      final newStart =
          centerTime.subtract(Duration(milliseconds: halfNewDuration));
      final newEnd = centerTime.add(Duration(milliseconds: halfNewDuration));

      // 验证新的时间范围
      if (newStart.isAfter(DateTime(1900)) && newEnd.isBefore(DateTime(2200))) {
        _viewportStart = newStart;
        _viewportEnd = newEnd;
        // 更新缩放级别
        setZoomLevel(_zoomLevel * scaleFactor);
        _saveToFile(); // 立即保存
      }
    } catch (e) {
      _resetToSafeRange();
    }
  }

  void _resetToSafeRange() {
    _viewportStart = DateTime.now().subtract(Duration(days: 365));
    _viewportEnd = DateTime.now().add(Duration(days: 365));
    _zoomLevel = 1.0;
    notifyListeners();
  }

  // 获取当前时间单位配置
  TimeUnitConfig get currentTimeUnit =>
      TimeUnitConfig.getCurrentUnit(_zoomLevel);

  void selectEvent(SpaxisEvent? event) {
    _selectedEvent = event;
    notifyListeners();
  }

  // 获取所有缩放档位（与TimeUnitConfig顺序一致）
  List<TimeUnitConfig> get zoomLevels => TimeUnitConfig.configs;

  // 获取当前缩放档位索引
  int get currentZoomLevelIndex {
    for (int i = 0; i < zoomLevels.length; i++) {
      if (_zoomLevel >= zoomLevels[i].minZoomLevel && _zoomLevel <= zoomLevels[i].maxZoomLevel) {
        return i;
      }
    }
    // 超出范围时返回最接近的
    if (_zoomLevel < zoomLevels.first.minZoomLevel) return 0;
    return zoomLevels.length - 1;
  }

  // 切换到下一个缩放档位（放大）
  void zoomInByLevel(double centerX, double canvasWidth) {
    int idx = currentZoomLevelIndex;
    if (idx <= 0) return; // 已是最大档
    final next = zoomLevels[idx - 1];
    _setZoomLevelByUnit(next, centerX, canvasWidth);
  }

  // 切换到上一个缩放档位（缩小）
  void zoomOutByLevel(double centerX, double canvasWidth) {
    int idx = currentZoomLevelIndex;
    if (idx >= zoomLevels.length - 1) return; // 已是最小档
    final next = zoomLevels[idx + 1];
    _setZoomLevelByUnit(next, centerX, canvasWidth);
  }

  // 以视口中心为基准切换缩放级别
  void _setZoomLevelByUnit(TimeUnitConfig unit, double centerX, double canvasWidth) {
    final currentDuration = viewportDurationMs;
    if (canvasWidth <= 0 || currentDuration <= 0) return;
    // 以中心点为基准，调整视口
    final centerRatio = centerX / canvasWidth;
    final centerTime = _viewportStart.add(Duration(milliseconds: (currentDuration * centerRatio).round()));
    final newDuration = unit.duration.inMilliseconds * 6; // 让每档大致显示6个单位
    final halfNewDuration = (newDuration / 2).round();
    final newStart = centerTime.subtract(Duration(milliseconds: halfNewDuration));
    final newEnd = centerTime.add(Duration(milliseconds: halfNewDuration));
    _viewportStart = newStart;
    _viewportEnd = newEnd;
    setZoomLevel((unit.minZoomLevel + unit.maxZoomLevel) / 2);
    notifyListeners();
  }

  // 将时间转换为画布坐标
  double timeToX(DateTime time, double canvasWidth) {
    if (canvasWidth <= 0) return 0;

    final totalDuration = viewportDurationMs;
    if (totalDuration <= 0) return 0;

    final timeFromStart = time.difference(_viewportStart).inMilliseconds;
    return (timeFromStart / totalDuration) * canvasWidth;
  }

  // 将画布坐标转换为时间
  DateTime xToTime(double x, double canvasWidth) {
    if (canvasWidth <= 0) return _viewportStart;

    final totalDuration = viewportDurationMs;
    final ratio = (x / canvasWidth).clamp(0.0, 1.0);
    final timeOffset = (totalDuration * ratio).round();
    return _viewportStart.add(Duration(milliseconds: timeOffset));
  }

  // 获取在当前缩放级别下应该显示的事件
  List<SpaxisEvent> getVisibleEvents() {
    if (_destinies.isEmpty || _selectedDestinyIndex < 0 || _selectedDestinyIndex >= _destinies.length) {
      return [];
    }
    return _destinies[_selectedDestinyIndex].events
        .where((event) =>
            (event.endTime == null
                ? event.startTime
                        .isAfter(_viewportStart.subtract(Duration(days: 1))) &&
                    event.startTime
                        .isBefore(_viewportEnd.add(Duration(days: 1)))
                : event.startTime.isBefore(_viewportEnd) &&
                    event.endTime!.isAfter(_viewportStart)))
        .toList();
  }

  Future<void> _saveToFile() async {
    try {
      final directory = await getApplicationDocumentsDirectory();
      final file = File('${directory.path}/spaxis_data.json');
      
      final data = {
        'destinies': _destinies.map((d) => d.toJson()).toList(),
        'selectedDestinyIndex': _selectedDestinyIndex,
        'viewportStart': _viewportStart.toIso8601String(),
        'viewportEnd': _viewportEnd.toIso8601String(),
        'zoomLevel': _zoomLevel,
        'trackCount': _trackCount,
      };
      await file.writeAsString(jsonEncode(data));
    } catch (e) {
      print('保存文件失败: $e');
    }
  }

  Future<void> loadFromFile() async {
    try {
      final directory = await getApplicationDocumentsDirectory();
      final file = File('${directory.path}/spaxis_data.json');
      
      if (await file.exists()) {
        final contents = await file.readAsString();
        final json = jsonDecode(contents);
        
        if (json.containsKey('destinies')) {
          _destinies = (json['destinies'] as List)
              .map((d) => Destiny.fromJson(d as Map<String, dynamic>))
              .toList();
        } else {
          // 兼容旧版本数据格式
          final events = (json['events'] as List)
              .map((e) => SpaxisEvent.fromJson(e as Map<String, dynamic>))
              .toList();
          _destinies = [
            Destiny(
              id: '1',
              name: json['timelineName'] ?? '我的命迹',
              events: events,
            )
          ];
        }
        
        _selectedDestinyIndex = json['selectedDestinyIndex'] ?? 0;
        
        if (json.containsKey('viewportStart')) {
          _viewportStart = DateTime.parse(json['viewportStart']);
        }
        if (json.containsKey('viewportEnd')) {
          _viewportEnd = DateTime.parse(json['viewportEnd']);
        }
        if (json.containsKey('zoomLevel')) {
          _zoomLevel = json['zoomLevel'].toDouble();
        }
        
        if (json.containsKey('trackCount')) {
          _trackCount = json['trackCount'] as int;
        }
        
        notifyListeners();
      } else {
        // 创建示例数据
        _createDefaultDestiny();
      }
    } catch (e) {
      print('加载文件失败: $e');
      _createDefaultDestiny();
    }
  }
}

class SpaxisHomePage extends StatefulWidget {
  @override
  _SpaxisHomePageState createState() => _SpaxisHomePageState();
}

class _SpaxisHomePageState extends State<SpaxisHomePage> {
  late SpaxisManager _manager;
  bool _isEditMode = false;
  int _selectedTab = 0;
  int _trackCount = 1; // 轨道数，默认1

  @override
  void initState() {
    super.initState();
    _manager = SpaxisManager();
    _manager.loadFromFile();
  }

  void _showRenameDialog(BuildContext context) {
    final TextEditingController controller = TextEditingController(
      text: _manager.timelineName,
    );

    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: Text('命名事件线'),
        content: TextField(
          controller: controller,
          decoration: InputDecoration(
            hintText: '请输入事件线名称',
          ),
          autofocus: true,
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: Text('取消'),
          ),
          TextButton(
            onPressed: () {
              if (controller.text.trim().isNotEmpty) {
                setState(() {
                  // 添加新命迹
                  _manager.addDestiny(controller.text.trim());
                });
              }
              Navigator.pop(context);
            },
            child: Text('保存'),
          ),
        ],
      ),
    );
  }

  // 添加导入对话框方法
  void _showImportDialog(BuildContext context) {
    final TextEditingController controller = TextEditingController();

    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: Text('导入事件文本'),
        content: TextField(
          controller: controller,
          decoration: InputDecoration(
            hintText: '请输入事件描述文本...',
            border: OutlineInputBorder(),
          ),
          maxLines: 5,
          autofocus: true,
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: Text('取消'),
          ),
          TextButton(
            onPressed: () async {
              if (controller.text.trim().isNotEmpty) {
                // 解析文本提取事件
                final events = TextParser.parseText(controller.text.trim());
                
                // 关闭当前对话框
                Navigator.pop(context);
                
                // 显示事件确认对话框
                if (events.isNotEmpty) {
                  _showEventsConfirmationDialog(context, events, _manager);
                }
              }
            },
            child: Text('解析'),
          ),
        ],
      ),
    );
  }

  // 添加命迹管理对话框
  void _showDestinyManagementDialog(BuildContext context) {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: Text('命迹管理'),
        content: Container(
          width: 300, // 设置固定宽度
          height: 400, // 设置固定高度
          child: Column(
            children: [
              // 移除Expanded，使用固定高度的ListView
              ListView.builder(
                  shrinkWrap: true,
                  itemCount: _manager.destinies.length,
                  itemBuilder: (context, index) {
                    final destiny = _manager.destinies[index];
                    return ListTile(
                      title: Text(destiny.name),
                      selected: index == _manager.selectedDestinyIndex,
                      onTap: () {
                        setState(() {
                          _manager.selectDestiny(index);
                        });
                        Navigator.pop(context);
                      },
                      trailing: IconButton(
                        icon: Icon(Icons.delete),
                        onPressed: () {
                          setState(() {
                            _manager.deleteDestiny(index);
                          });
                        },
                      ),
                    );
                  },
                ),
              SizedBox(height: 20),
              // +号按钮用于新增命迹
              FloatingActionButton(
                onPressed: () => _showAddDestinyDialog(context),
                child: Icon(Icons.add),
                mini: true,
              ),
            ],
          ),
        ),
      ),
    );
  }

  // 添加新增命迹对话框
  void _showAddDestinyDialog(BuildContext context) {
    final TextEditingController controller = TextEditingController();

    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: Text('新增命迹'),
        content: TextField(
          controller: controller,
          decoration: InputDecoration(
            hintText: '请输入命迹名称',
          ),
          autofocus: true,
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: Text('取消'),
          ),
          TextButton(
            onPressed: () {
              if (controller.text.trim().isNotEmpty) {
                // 这里将实现创建新命迹的逻辑
                setState(() {
                    _manager.addDestiny(controller.text.trim());
                  });
                Navigator.pop(context);
              }
            },
            child: Text('创建'),
          ),
        ],
      ),
    );
  }

  // 添加事件确认对话框实现
  void _showEventsConfirmationDialog(BuildContext context, List<SpaxisEvent> events, SpaxisManager manager) {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: Text('确认事件信息'),
        content: Container(
          width: double.maxFinite,
          child: SingleChildScrollView(
            child: Column(
              children: events.map((event) {
                return Card(
                  margin: EdgeInsets.symmetric(vertical: 8),
                  child: Padding(
                    padding: EdgeInsets.all(12),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        TextFormField(
                          initialValue: event.title,
                          decoration: InputDecoration(
                            labelText: '事件标题',
                            border: OutlineInputBorder(),
                          ),
                          onChanged: (value) => event.title = value,
                        ),
                        SizedBox(height: 8),
                        Row(
                          children: [
                            Expanded(
                              child: TextFormField(
                                initialValue: DateFormat('yyyy-MM-dd').format(event.startTime),
                                decoration: InputDecoration(
                                  labelText: '开始时间',
                                  border: OutlineInputBorder(),
                                ),
                                onChanged: (value) {
                                  try {
                                    event.startTime = DateFormat('yyyy-MM-dd').parse(value);
                                  } catch (_) {}
                                },
                              ),
                            ),
                            SizedBox(width: 8),
                            Expanded(
                              child: TextFormField(
                                initialValue: event.endTime != null 
                                    ? DateFormat('yyyy-MM-dd').format(event.endTime!)
                                    : DateFormat('yyyy-MM-dd').format(event.startTime.add(Duration(days: 1))),
                                decoration: InputDecoration(
                                  labelText: '结束时间',
                                  border: OutlineInputBorder(),
                                ),
                                onChanged: (value) {
                                  try {
                                    event.endTime = DateFormat('yyyy-MM-dd').parse(value);
                                  } catch (_) {}
                                },
                              ),
                            ),
                          ],
                        ),
                        SizedBox(height: 8),
                        TextFormField(
                          initialValue: event.description,
                          decoration: InputDecoration(
                            labelText: '事件描述',
                            border: OutlineInputBorder(),
                          ),
                          maxLines: 2,
                          onChanged: (value) => event.description = value,
                        ),
                      ],
                    ),
                  ),
                );
              }).toList(),
            ),
          ),
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: Text('取消'),
          ),
          TextButton(
            onPressed: () {
              // 添加所有事件到时间线
              events.forEach((event) {
                manager.addEvent(event);
              });
              
              // 调整视口以显示新添加的事件
              if (events.isNotEmpty) {
                final earliestEvent = events.reduce((a, b) => a.startTime.isBefore(b.startTime) ? a : b);
                final latestEvent = events.reduce((a, b) => a.startTime.isAfter(b.startTime) ? a : b);
                
                // 设置视口范围，包含所有新事件，并留出一些边距
                final viewportStart = earliestEvent.startTime.subtract(Duration(days: 30));
                final viewportEnd = latestEvent.startTime.add(Duration(days: 30));
                
                manager.setViewport(viewportStart, viewportEnd);
                
                // 调整缩放级别以确保事件可见
                manager.setZoomLevel(1.0);
              }
              
              Navigator.pop(context);
              
              // 显示成功提示
              ScaffoldMessenger.of(context).showSnackBar(
                SnackBar(content: Text('成功添加 ${events.length} 个事件')),
              );
            },
            child: Text('添加事件'),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    // 统一背景色
    const bgColor = Color(0xFFF5F5F5); // 与设置页、用户页一致的浅灰色
    return Scaffold(
      backgroundColor: bgColor,
      body: IndexedStack(
        index: _selectedTab,
        children: [
          // spaxis 时间轴界面
          Container(
            color: bgColor,
            child: Stack(
              children: [
                Column(
                  children: [
                    _buildInfoPanel(),
                    Expanded(
                      child: AnimatedBuilder(
                        animation: _manager,
                        builder: (context, child) {
                          return TimelineCanvas(
                            manager: _manager,
                            isEditMode: _isEditMode,
                            onEventTap: _showEventDetails,
                            onLongPress: _showContextMenu,
                            trackCount: _trackCount,
                          );
                        },
                      ),
                    ),
                  ],
                ),
                // 左下角日期上方一段距离的缩放按钮
                Positioned(
                  left: 24,
                  bottom: 180, // 比缩放按钮更高，保证在其上方
                  child: AnimatedBuilder(
                    animation: _manager,
                    builder: (context, child) {
                      return Column(
                        children: [
                          _ZoomButton(
                            icon: Icons.access_time,
                            onTap: () {
                              final now = DateTime.now();
                              // 以当前时间为中心，跨度6小时（时级）
                              final start = now.subtract(Duration(hours: 3));
                              final end = now.add(Duration(hours: 3));
                              _manager.setViewport(start, end);
                              // 设置缩放级别为"时级"
                              // 查找时级缩放区间
                              final hourConfig = TimeUnitConfig.configs.firstWhere((c) => c.unit == TimeUnit.hour);
                              _manager.setZoomLevel((hourConfig.minZoomLevel + hourConfig.maxZoomLevel) / 2);
                            },
                          ),
                          SizedBox(height: 18),
                        ],
                      );
                    },
                  ),
                ),
                // 左下角日期上方一段距离的缩放按钮
                Positioned(
                  left: 24,
                  bottom: 100, // 距离底部100像素，保证在日期上方
                  child: AnimatedBuilder(
                    animation: _manager,
                    builder: (context, child) {
                      final idx = _manager.currentZoomLevelIndex;
                      return Column(
                        children: [
                          _ZoomButton(
                            icon: Icons.add,
                            onTap: idx > 0
                                ? () {
                                    final RenderBox? box = context.findRenderObject() as RenderBox?;
                                    final width = box?.size.width ?? MediaQuery.of(context).size.width;
                                    _manager.zoomInByLevel(width / 2, width);
                                  }
                                : null,
                          ),
                          SizedBox(height: 12),
                          _ZoomButton(
                            icon: Icons.remove,
                            onTap: idx < _manager.zoomLevels.length - 1
                                ? () {
                                    final RenderBox? box = context.findRenderObject() as RenderBox?;
                                    final width = box?.size.width ?? MediaQuery.of(context).size.width;
                                    _manager.zoomOutByLevel(width / 2, width);
                                  }
                                : null,
                          ),
                        ],
                      );
                    },
                  ),
                ),
              ],
            ),
          ),
          // set 设置界面
          Container(
            color: bgColor,
            child: _buildSettingsPage(),
          ),
          // user 空白界面
          Container(
            color: bgColor,
            child: Center(child: Text('')),
          ),
        ],
      ),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _selectedTab,
        onTap: (index) {
          setState(() {
            _selectedTab = index;
          });
        },
        items: const [
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: '命迹',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.settings),
            label: '设置',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.person),
            label: '用户',
          ),
        ],
      ),
      // 移除原有AppBar和按钮
    );
  }

  Widget _buildInfoPanel() {
    return AnimatedBuilder(
      animation: _manager,
      builder: (context, child) {
        return Align(
          alignment: Alignment.topLeft,
          child: Padding(
            padding: const EdgeInsets.only(left: 12, top: 8),
            child: Row(
            children: [
              // 添加命名按钮
              ElevatedButton(
            onPressed: () => _showRenameDialog(context), // 修复方法调用
            style: ElevatedButton.styleFrom(
              backgroundColor: Colors.blue,
              padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6),
              textStyle: TextStyle(fontSize: 14),
            ),
            child: Text(
              _manager.timelineName.isEmpty ? '命名时间线' : _manager.timelineName,
              overflow: TextOverflow.ellipsis,
            ),
          ),
              SizedBox(width: 16),
            // 添加导入按钮
            ElevatedButton(
              onPressed: () => _showImportDialog(context),
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors.green,
                padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6),
                textStyle: TextStyle(fontSize: 14),
              ),
              child: Text('导入'),
            ),
            SizedBox(width: 16),
              // 添加回顾按钮
              ElevatedButton(
            onPressed: () => Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => ReviewSettingsPage(manager: _manager)),
            ),
            style: ElevatedButton.styleFrom(
              backgroundColor: Colors.purple,
              padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6),
              textStyle: TextStyle(fontSize: 14),
            ),
            child: Text('回顾'),
          ),
          SizedBox(width: 16),
          // 添加命迹管理图标按钮
          IconButton(
            icon: Icon(Icons.settings, color: Colors.grey[600]),
            onPressed: () => _showDestinyManagementDialog(context),
          ),
          // 原有的信息文本
          Text(
                '缩放: ${_manager.zoomLevel.toStringAsFixed(1)}x  |  事件数: ${_manager.events.length}  |  可见: ${_manager.getVisibleEvents().length}',
                style: TextStyle(
                  color: Colors.grey[600],
                  fontSize: 12,
                ),
              ),
            ],
          ),
          ),
        );
      },
    );
  }

  Widget _buildSettingsPage() {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text('轨道数',
              style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
          SizedBox(height: 16),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: List.generate(5, (i) { // 改为1-5
              final value = i + 1;
              return Padding(
                padding: const EdgeInsets.symmetric(horizontal: 8.0),
                child: ChoiceChip(
                  label: Text('$value'),
                  selected: _trackCount == value,
                  onSelected: (selected) {
                    setState(() {
                      _trackCount = value;
                    });
                  },
                ),
              );
            }),
          ),
          SizedBox(height: 8),
          Text('（1-5，事件采用先来抢占机制，若轨道满则占最低轨道，默认1）',
              style: TextStyle(fontSize: 13, color: Colors.grey[600])),
        ],
      ),
    );
  }

  void _showEventDetails(SpaxisEvent event) {
    showDialog(
      context: context,
      builder: (context) => EventDetailsDialog(
        event: event,
        manager: _manager,
      ),
    );
  }



  void _showContextMenu(Offset position) {
    final renderBox = context.findRenderObject() as RenderBox;
    final time = _manager.xToTime(position.dx, renderBox.size.width);
    showMenu(
      context: context,
      position: RelativeRect.fromLTRB(
        position.dx,
        position.dy,
        position.dx + 1,
        position.dy + 1,
      ),
      items: [
        PopupMenuItem(
          child: Text('在此时间添加事件'),
          value: 'add',
        ),
      ],
    ).then((value) {
      if (value == 'add') {
        showDialog(
          context: context,
          builder: (context) => EventEditDialog(
            manager: _manager,
            initialTime: time,
          ),
        );
      }
    });
  }
}



class TimelineCanvas extends StatefulWidget {
  final SpaxisManager manager;
  final bool isEditMode;
  final Function(SpaxisEvent) onEventTap;
  final Function(Offset) onLongPress;
  final int trackCount;

  const TimelineCanvas({
    Key? key,
    required this.manager,
    required this.isEditMode,
    required this.onEventTap,
    required this.onLongPress,
    this.trackCount = 1,
  }) : super(key: key);

  @override
  _TimelineCanvasState createState() => _TimelineCanvasState();
}

// 改进的手势处理，在TimelineCanvas中替换现有的手势检测
class _TimelineCanvasState extends State<TimelineCanvas> with SingleTickerProviderStateMixin {
  double _lastPanX = 0;
  double _lastScale = 1.0;
  bool _isPanning = false;

  AnimationController? _inertiaController;
  Animation<double>? _inertiaAnimation;
  double _lastInertiaValue = 0.0;

  @override
  void initState() {
    super.initState();
    _inertiaController = AnimationController(vsync: this);
  }

  @override
  void dispose() {
    _inertiaController?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onScaleStart: (details) {
        _lastScale = 1.0;
        _lastPanX = details.localFocalPoint.dx;
        _isPanning = false;
        _inertiaController?.stop(); // 立即停止动画，防止冲突
        // _lastPanViewport = 0.0;
        _lastInertiaValue = 0.0; // 保证惯性动画起点归零
      },
      onScaleUpdate: (details) {
        if ((details.scale - _lastScale).abs() > 0.01) {
          final scaleFactor = details.scale / _lastScale;
          widget.manager.zoomViewport(
            scaleFactor,
            context.size!.width / 2,
            context.size!.width,
          );
          _lastScale = details.scale;
          _isPanning = false;
        }
        if (!_isPanning && details.scale == 1.0) {
          _isPanning = true;
        }
        if (_isPanning && details.scale == 1.0) {
          final deltaX = _lastPanX - details.localFocalPoint.dx;
          if (deltaX.abs() > 1.0) {
            widget.manager.panViewport(deltaX, context.size!.width);
            _lastPanX = details.localFocalPoint.dx;
            // _lastPanViewport = deltaX; // 记录最后一次滑动的偏移
          }
        }
      },
      onScaleEnd: (details) {
        // 不要再补 panViewport，直接启动惯性动画
        if (_isPanning && details.velocity.pixelsPerSecond.dx.abs() > 50) {
          _lastInertiaValue = 0.0; // 启动前归零
          _startInertiaPhysics(details.velocity.pixelsPerSecond.dx, context.size!.width);
        }
      },
      onTapDown: (details) {
        _handleTap(details.localPosition, context.size!);
      },
      onLongPressStart: (details) {
        widget.onLongPress(details.localPosition);
        HapticFeedback.mediumImpact();
      },
      child: CustomPaint(
        painter: TimelinePainter(
          manager: widget.manager,
          isEditMode: widget.isEditMode,
          onEventTap: widget.onEventTap,
          trackCount: widget.trackCount,
        ),
        size: Size.infinite,
      ),
    );
  }

  void _startInertiaPhysics(double velocity, double canvasWidth) {
    // velocity: px/s
    if (velocity.abs() < 10) return; // 速度太小不启动动画
    _inertiaController?.stop();
    _inertiaController?.reset();
    _lastInertiaValue = 0.0; // 关键：每次动画前重置
    // 固定动画时长，线性衰减
    const double duration = 0.8; // 秒
    final double totalDistance = velocity * duration * 0.5; // 线性衰减，末速度为0，平均速度0.5
    _inertiaController?.duration = Duration(milliseconds: (duration * 1000).ceil());
    _inertiaAnimation = Tween<double>(begin: 0, end: totalDistance).animate(CurvedAnimation(
      parent: _inertiaController!,
      curve: Curves.decelerate,
    ))
      ..addListener(() {
        final displacement = _inertiaAnimation!.value;
        final delta = displacement - _lastInertiaValue;
        if (delta.abs() > 0.1) {
          widget.manager.panViewport(-delta, canvasWidth);
          _lastInertiaValue = displacement;
        }
      })
      ..addStatusListener((status) {
        if (status == AnimationStatus.completed || status == AnimationStatus.dismissed) {
          _lastInertiaValue = 0.0; // 动画结束后归零
        }
      });
    _inertiaController?.forward();
  }

  // 添加轨道分配方法
  Map<String, int> _assignEventTracks(List<SpaxisEvent> events, double canvasWidth) {
    final sorted = List<SpaxisEvent>.from(events)
      ..sort((a, b) {
        final cmp = a.startTime.compareTo(b.startTime);
        if (cmp != 0) return cmp;
        return a.id.compareTo(b.id);
      });
    final List<DateTime?> trackEndTimes = List.filled(widget.trackCount, null);
    final Map<String, int> assignments = {};
    for (final event in sorted) {
      int assignedTrack = 0;
      for (int t = 0; t < widget.trackCount; t++) {
        final lastEnd = trackEndTimes[t];
        final eventStart = event.startTime;
        final eventEnd = event.endTime ?? event.startTime.add(Duration(minutes: 1));
        if (lastEnd == null || !eventStart.isBefore(lastEnd)) {
          assignedTrack = t;
          trackEndTimes[t] = eventEnd;
          break;
        }
      }
      assignments[event.id] = assignedTrack;
    }
    return assignments;
  }

  void _handleTap(Offset position, Size size) {
    final tapOffset = position;
    final visibleEvents = widget.manager.getVisibleEvents();
    final trackAssignments = _assignEventTracks(visibleEvents, size.width);

  // 添加事件透明度计算方法
  double _calculateEventAlpha(SpaxisEvent event, Size size) {
    final startX = widget.manager.timeToX(event.startTime, size.width);
    final endX = event.endTime != null
        ? widget.manager.timeToX(event.endTime!, size.width)
        : startX + math.max(20, 80 * widget.manager.zoomLevel);
    final width = (endX - startX).abs();
    final ratio = width / size.width;
    const minRatio = 0.2;
    const maxRatio = 1.0;
    const centerRatio = 1.0 / 3.0;
    const minAlpha = 0.7;
    const maxAlpha = 1.0;
    double alpha;
    if (ratio < minRatio) {
      alpha = minAlpha - (minRatio - ratio) * 3.0;
    } else if (ratio > maxRatio) {
      alpha = minAlpha - (ratio - maxRatio) * 2.5;
    } else if (ratio < centerRatio) {
      alpha = minAlpha + (maxAlpha - minAlpha) * (ratio - minRatio) / (centerRatio - minRatio);
    } else {
      alpha = maxAlpha - (maxAlpha - minAlpha) * (ratio - centerRatio) / (maxRatio - centerRatio);
    }
    if (alpha < 0.01) return 0.0;
    return alpha.clamp(0.0, 1.0);
  }

    // 收集所有命中的事件及其alpha
    final List<HitEvent> hitEvents = [];
    for (final event in visibleEvents) {
      if (event.endTime != null) {
        // 时间段事件，原有逻辑
        final track = trackAssignments[event.id] ?? 0;
        final startX = widget.manager.timeToX(event.startTime, size.width);
        final endX = widget.manager.timeToX(event.endTime!, size.width);
        final trackHeight = TimelineUtils.calcTrackHeight(size.height, widget.trackCount);
        final y = TimelineUtils.calcTrackY(size.height, track, widget.trackCount);
        if (y < -90000) continue; // 不可见
        final rect = Rect.fromLTRB(
          startX,
          y,
          endX,
          y + trackHeight,
        );
        if (rect.contains(tapOffset)) {
          final alpha = _calculateEventAlpha(event, size);
          hitEvents.add(HitEvent(event, alpha));
        }
      } else {
        // 时间点事件，判定圆点
        final x = widget.manager.timeToX(event.startTime, size.width);
        final centerY = size.height / 2;
        const distanceFromAxis = 60.0;
        final dotY = centerY + distanceFromAxis + size.height / 30 / 2 + 2;
        final diameter = size.height / 30;
        final dotRect = Rect.fromCircle(center: Offset(x, dotY), radius: diameter / 2 + 6); // 适当扩大判定
        if (dotRect.contains(tapOffset)) {
          hitEvents.add(HitEvent(event, 1.0));
        }
      }
    }
    // 选出alpha最大的事件
    if (hitEvents.isNotEmpty) {
      hitEvents.sort((a, b) => b.alpha.compareTo(a.alpha));
      widget.onEventTap(hitEvents.first.event);
      return;
    }
    widget.manager.selectEvent(null);
  }
}

// 时间单位配置
class TimeUnitConfig {
  final TimeUnit unit;
  final Duration duration;
  final String label;
  final double minZoomLevel;
  final double maxZoomLevel;

  const TimeUnitConfig({
    required this.unit,
    required this.duration,
    required this.label,
    required this.minZoomLevel,
    required this.maxZoomLevel,
  });

  static const List<TimeUnitConfig> configs = [
    TimeUnitConfig(
      unit: TimeUnit.decade,
      duration: Duration(days: 3652), // 约10年
      label: '年',
      minZoomLevel: 0.01,
      maxZoomLevel: 0.1,
    ),
    TimeUnitConfig(
      unit: TimeUnit.year,
      duration: Duration(days: 365),
      label: '年',
      minZoomLevel: 0.1,
      maxZoomLevel: 1.0,
    ),
    TimeUnitConfig(
      unit: TimeUnit.month,
      duration: Duration(days: 30),
      label: '月',
      minZoomLevel: 1.0,
      maxZoomLevel: 12.0,
    ),
    TimeUnitConfig(
      unit: TimeUnit.day,
      duration: Duration(days: 1),
      label: '日',
      minZoomLevel: 12.0,
      maxZoomLevel: 365.0,
    ),
    TimeUnitConfig(
      unit: TimeUnit.hour,
      duration: Duration(hours: 1),
      label: '时',
      minZoomLevel: 365.0,
      maxZoomLevel: 8760.0,
    ),
    TimeUnitConfig(
      unit: TimeUnit.minute,
      duration: Duration(minutes: 1),
      label: '分',
      minZoomLevel: 8760.0,
      maxZoomLevel: 525600.0,
    ),
  ];

  static TimeUnitConfig getCurrentUnit(double zoomLevel) {
    for (final config in configs) {
      if (zoomLevel >= config.minZoomLevel &&
          zoomLevel <= config.maxZoomLevel) {
        return config;
      }
    }
    // 如果超出范围，返回最接近的
    if (zoomLevel < configs.first.minZoomLevel) {
      return configs.first;
    }
    return configs.last;
  }
}

// 小圆形缩放按钮组件
class _ZoomButton extends StatelessWidget {
  final IconData icon;
  final VoidCallback? onTap;
  const _ZoomButton({required this.icon, this.onTap});
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onTap,
      child: Opacity(
        opacity: onTap == null ? 0.4 : 1.0,
        child: Container(
          width: 36,
          height: 36,
          decoration: BoxDecoration(
            color: Colors.white,
            shape: BoxShape.circle,
            boxShadow: [
              BoxShadow(
                color: Colors.black12,
                blurRadius: 4,
                offset: Offset(0, 2),
              ),
            ],
            border: Border.all(color: Colors.grey[300]!),
          ),
          child: Icon(icon, size: 22, color: Colors.blueGrey),
        ),
      ),
    );
  }
}

class EventEditDialog extends StatefulWidget {
  final SpaxisManager manager;
  final DateTime initialTime;
  final SpaxisEvent? event;

  const EventEditDialog({
    Key? key,
    required this.manager,
    required this.initialTime,
    this.event,
  }) : super(key: key);

  @override
  _EventEditDialogState createState() => _EventEditDialogState();
}

// EventEditDialog State
class _EventEditDialogState extends State<EventEditDialog> {
  late TextEditingController _titleController;
  late TextEditingController _descriptionController;
  late DateTime _startTime;
  DateTime? _endTime;
  Color _selectedColor = Colors.blue;
  bool _isPointEvent = false; // 默认时间段
  String? _backgroundImagePath; // 新增背景图片路径变量

  @override
  void initState() {
    super.initState();
    _titleController = TextEditingController(text: widget.event?.title ?? '');
    _descriptionController = TextEditingController(text: widget.event?.description ?? '');
    _startTime = widget.event?.startTime ?? widget.initialTime;
    _endTime = widget.event?.endTime ?? _startTime.add(Duration(days: 1)); // 默认1天
    _selectedColor = widget.event?.color ?? Colors.blue;
    _isPointEvent = widget.event?.endTime == null;
    _backgroundImagePath = widget.event?.backgroundImagePath; // 初始化背景图片路径
  }

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Text(widget.event == null ? '添加事件' : '编辑事件'),
      content: SingleChildScrollView(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            TextField(
              controller: _titleController,
              decoration: InputDecoration(labelText: '事件标题'),
            ),
            // 添加背景图片按钮
            SizedBox(height: 16),
            TextField(
              controller: _descriptionController,
              decoration: InputDecoration(labelText: '描述'),
              minLines: 3,
              maxLines: null,
              keyboardType: TextInputType.multiline,
            ),
            SizedBox(height: 16),
            Row(
              children: [
                Text('事件类型: '),
                Switch(
                  value: _isPointEvent,
                  onChanged: (value) {
                    setState(() {
                      _isPointEvent = value;
                      _endTime = value ? null : _startTime.add(Duration(days: 1));
                    });
                  },
                ),
                Text(_isPointEvent ? '时间点' : '时间段'),
              ],
            ),
            SizedBox(height: 16),
            ListTile(
              title: Text('开始时间'),
              subtitle: Text(
                  '${_startTime.year}/${_startTime.month}/${_startTime.day}'),
              trailing: Icon(Icons.calendar_today),
              onTap: () async {
                final date = await showDatePicker(
                  context: context,
                  initialDate: _startTime,
                  firstDate: DateTime(2000),
                  lastDate: DateTime(2100),
                );
                if (date != null) {
                  setState(() {
                    _startTime = date;
                  });
                }
              },
            ),
            if (!_isPointEvent)
              ListTile(
                title: Text('结束时间'),
                subtitle: Text(_endTime != null
                    ? '${_endTime!.year}/${_endTime!.month}/${_endTime!.day}'
                    : '未设置'),
                trailing: Icon(Icons.calendar_today),
                onTap: () async {
                  final date = await showDatePicker(
                    context: context,
                    initialDate: _endTime ?? _startTime.add(Duration(days: 1)),
                    firstDate: _startTime,
                    lastDate: DateTime(2100),
                  );
                  if (date != null) {
                    setState(() {
                      _endTime = date;
                    });
                  }
                },
              ),
            SizedBox(height: 16),
            Wrap(
              children: [
                Colors.blue,
                Colors.green,
                Colors.orange,
                Colors.red,
                Colors.purple,
                Colors.pink,
              ].map((color) {
                return GestureDetector(
                  onTap: () {
                    setState(() {
                      _selectedColor = color;
                    });
                  },
                  child: Container(
                    width: 40,
                    height: 40,
                    margin: EdgeInsets.all(4),
                    decoration: BoxDecoration(
                      color: color,
                      shape: BoxShape.circle,
                      border: _selectedColor == color
                          ? Border.all(color: Colors.black, width: 3)
                          : null,
                    ),
                  ),
                );
              }).toList(),
            ),
            if (_backgroundImagePath != null) ...[
              SizedBox(height: 16),
              Container(
                height: 120,
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(8),
                  border: Border.all(color: Colors.grey),
                  image: DecorationImage(
                    image: FileImage(File(_backgroundImagePath!)),
                    fit: BoxFit.cover,
                  ),
                ),
              ),
            ],
            SizedBox(height: 16),
            ElevatedButton.icon(
              onPressed: _pickBackgroundImage,
              icon: Icon(Icons.image),
              label: Text('设置背景图片'),
            ),
          ],
        ),
      ),
      actions: [
        TextButton(
          onPressed: () => Navigator.of(context).pop(),
          child: Text('取消'),
        ),
        if (widget.event != null)
          TextButton(
            onPressed: () {
              widget.manager.removeEvent(widget.event!.id);
              Navigator.of(context).pop();
            },
            child: Text('删除', style: TextStyle(color: Colors.red)),
          ),
        ElevatedButton(
          onPressed: _saveEvent,
          child: Text('保存'),
        ),
      ],
    );
  }

  void _saveEvent() {
    if (_titleController.text.trim().isEmpty) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('请输入事件标题')),
      );
      return;
    }

    final event = SpaxisEvent(
      id: widget.event?.id ?? DateTime.now().millisecondsSinceEpoch.toString(),
      title: _titleController.text.trim(),
      startTime: _startTime,
      endTime: _isPointEvent ? null : _endTime,
      description: _descriptionController.text.trim(),
      color: _selectedColor,
      backgroundImagePath: _backgroundImagePath, // 保存背景图片路径
      backgroundMusicPath: null,
    );

    if (widget.event == null) {
      widget.manager.addEvent(event);
    } else {
      widget.manager.updateEvent(event);
    }

    Navigator.of(context).pop();
  }

  // 实现图片选择方法
  Future<void> _pickBackgroundImage() async {
    try {
      final pickedFile = await ImagePicker().pickImage(
        source: ImageSource.gallery,
        imageQuality: 80,
      );

      if (pickedFile != null) {
        setState(() {
          _backgroundImagePath = pickedFile.path;
        });
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('背景图片已选择')),
        );
      }
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('图片选择失败: ${e.toString()}'), backgroundColor: Colors.red),
      );
    }
  }

}

class EventDetailsDialog extends StatelessWidget {
  final SpaxisEvent event;
  final SpaxisManager manager;

  const EventDetailsDialog({
    Key? key,
    required this.event,
    required this.manager,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Text(event.title),
      content: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          if (event.description.isNotEmpty) ...[
            Text('描述:', style: TextStyle(fontWeight: FontWeight.bold)),
            Text(event.description),
            SizedBox(height: 16),
          ],
          Text('开始时间:', style: TextStyle(fontWeight: FontWeight.bold)),
          Text(
              '${event.startTime.year}年${event.startTime.month}月${event.startTime.day}日'),
          if (event.endTime != null) ...[
            SizedBox(height: 8),
            Text('结束时间:', style: TextStyle(fontWeight: FontWeight.bold)),
            Text(
                '${event.endTime!.year}年${event.endTime!.month}月${event.endTime!.day}日'),
            SizedBox(height: 8),
            Text('持续时间:', style: TextStyle(fontWeight: FontWeight.bold)),
            Text('${event.endTime!.difference(event.startTime).inDays}天'),
          ],
        ],
      ),
      actions: [
        TextButton(
          onPressed: () => Navigator.of(context).pop(),
          child: Text('关闭'),
        ),
        ElevatedButton(
          onPressed: () {
            Navigator.of(context).pop();
            showDialog(
              context: context,
              builder: (context) => EventEditDialog(
                manager: manager,
                initialTime: event.startTime,
                event: event,
              ),
            );
          },
          child: Text('编辑'),
        ),
      ],
    );
  }
}
